/**
 * Author(s): xuming.Wong <xuming.Wong@gmail.com>
 */
#ifndef __M2_FILE_H__
#define __M2_FILE_H__

#include "M2.h"
#include "MPQArchive.h"

namespace PQGame
{
	/*class that load m2 file
	*/
	class M2File
	{	
	public:
		~M2File(void);
		M2File(PQEngine::FileBase* file);

		inline bool ok()
		{
			return _ok;
		}

		inline std::string getFileName()
		{
			return _fileName;
			
		}

		inline std::string getSkinFileName()
		{
			std::string path =_fileName.substr(0, _fileName.length()-3);//remove .m2
			std::string skinPath=path+"00.skin";
			return skinPath;
		}
		
		inline int getVerticesCount()
		{
			if(_header!=0){
				return _header->nVertices;
			}else{
				return 0;
			}
		}

		inline M2Vertex *getVerticesPtr()
		{
			return _vertices;
		}


		inline int getBoneCount()
		{
			if(_header!=0){
				return _header->nBones;
			}else{
				return 0;
			}
		}

		inline M2Bone* getBonePtr()
		{
			return _bones;
		}


		inline char* getBuffer()
		{
			return _buf;
		}

		inline unsigned int *getGlobSeqPtr()
		{
			return _globSeqs;
		}

		inline int getSize()
		{
			return _fileSize;
		}

		inline M2AnimBlockHeader* getAnimBlockHeader(int offset,int index)
		{
			M2AnimBlockHeader* _header=(M2AnimBlockHeader*)(_buf+offset+index*sizeof(M2AnimBlockHeader));
			return _header;
		}


		inline int getLightsCount()
		{
			if(_header!=0){
				return _header->nLights;
			}else{
				return 0;
			}
		}

		inline M2Light* getLightsPtr()
		{
			return _m2Lights;
		}

		inline M2Animation *getAnimsPtr()
		{
			return _m2Anims;
		}

		inline int getAnimCount()
		{
			if(_header!=0){
				return _header->nAnims;
			}else{
				return 0;
			}
		}

		inline int getAnimId(int index)
		{
			if(index>=_header->nAnims){
				return -1;
			}

			if(_m2Anims!=0){
				return _m2Anims[index].animId;
			}else{
				return -1;
			}
			
		}

		inline int getSubAnimId(int index)
		{
			if(index>=_header->nAnims){
				return -1;
			}

			if(_m2Anims!=0){
				return _m2Anims[index].subAnimId;
			}else{
				return -1;
			}
			
		}

		inline short *getTexUnitLookupPtr()
		{
			return _m2TexUnitLookup;
		}

		inline unsigned short *getTexAnimLookupPtr()
		{
			return _m2TexAnimLookup;
		}

		inline unsigned short *getTexLookupPtr()
		{
			return _m2TexLookup;
		}

		inline M2RenderFlag *getRenderFlagsPtr()
		{
			return _m2RenderFlag;
		}

		inline short* getTransLookupPtr()
		{
			return _m2TranspLookup;
		}

		inline M2TexDef* getTexDefs()
		{
			return _m2TexDefs;
		}

		inline int getTexCount()
		{
			return _header->nTex;
		}

		inline std::string getTexName(int index)
		{
			std::string texName(_buf+_m2TexDefs[index].nameOfs,_m2TexDefs[index].nameLen);
			return texName;
			
		}

		inline bool isTexAnimated()
		{
			return _header->nTexAnims> 0;
		}
	private:
		bool parse();
	private:
		std::string _fileName;
		int _fileSize;
		char* _buf;
		bool _ok;
		
		M2Header *_header;

		unsigned int *_globSeqs;
		M2Bone *_bones;
		M2Vertex *_vertices;//_vertices ptr to m2 file data
		M2Color *_colors;//color ptr to m2 file data
		M2Transp *_transps;//color ptr to m2 file data
		M2TexDef* _m2TexDefs;

		M2Animation* _m2Anims;//animation sequences ptr for animated model
		short* _m2AnimLookup;//
		
		M2TexAnim *_m2TexAnims;
		M2ParticleEmitter *_m2ParticleEmitters;
		M2RibbonEmitter *_m2RibbonEmitters;
		M2Camera *_m2Cameras;
		M2Light *_m2Lights;

		//for texture render
		M2RenderFlag *_m2RenderFlag;
		unsigned short *_m2TexLookup;
		unsigned short *_m2TexAnimLookup;
		short *_m2TexUnitLookup;
		short *_m2TranspLookup;
		short *_m2KeyBoneLookup;

	};
}
#endif
